<!DOCTYPE html>
<html>
	<head>
		<title>Sqrat Threading - Threading Utilities</title>
		
		<link type="text/css" href="style.css" rel="stylesheet" />
	</head>
	
	<body>
	
	<div id="header">
		<h1>Sqrat Threading - Threading Utilities</h1>
		<h3>(c) 2009 Brandon Jones</h3>
	</div>
		
	<div id="index">
		<h2>Table of Contents</h2>
		
		<ul>
			<li><a href="index.html">Home</a></li>
			<li><a href="binding.html">Binding Library</a></li>
			<li><a href="import.html">Module Import Library</a></li>
			<li><a href="threading.html">Threading Module</a>
				<ul>
					<li><a href="#overview">Overview</a></li>
					<li><a href="#functions">Functions</a>
						<ul>
							<li><a href="#schedule">schedule</a></li>
							<li><a href="#run">run</a></li>
							<li><a href="#sleep">sleep</a></li>
							<li><a href="#getthread">getthread</a></li>
						</ul>
					</li>
				</ul>
			</li>
		</ul>
		
	</div>
		
	<div id="text">
	
		<h2 id="overview">Overview</h2>
		
		<p>Sqrat Threading is a utility module for Squirrel that aims to provide new
		and useful capabilities to Sqrat's existing threading model.</p>
		
		<p>Sqrat Threading is a standalone module intended for use with Sqrat Import.
		It has no dependancy on the Sqrat Binding library.</p>
	
		<h2 id="functions">Functions</h2>
		
		<h3 id="schedule"><i>paramFunc</i> <b>schedule</b>(<i>threadFunc</i>)</h3>
		
		<p>schedule creates a new thread and adds it to a simple round-robin scheduler. 
		Scheduled threads run in the order they were added, rotating through the list as
		each thread yields it's execution. Scheduled tasks are executed by calling 
		<a href="#run">run</a>.</p>
		
	<pre>
	thread &lt;- ::import("sqratthread", {});
	
	function funcA() {
		::print("Called A");
	}
	
	function funcB() {
		::print("Called A");
	}
	
	thread.schedule(funcA);
	thread.schedule(funcB);
	thread.run(); // Runs funcA, then funcB
	</pre>
		
		<p>When schedule is called a function is returned that takes the parameters to
		call the thread function with when it is run. Any number of parameters can be 
		passed in this way.</p>
	
	<pre>
	function threadPrint(arg) {
		::print(arg);
	}
	
	function printSum(a, b) {
		::print(a + b);
	}

	thread.schedule(threadPrint)("Hello");
	thread.schedule(threadPrint)("World");
	thread.schedule(printSum)(12, 30);
	thread.run();
	</pre>
	
		<p>Scheduled threads can be suspended just like any other thread, which will allow
		execution to proceed to the next scheduled thread. Once all threads have suspended
		or yielded execution the scheduler starts over on the first remaining thread, waking
		it up automatically and continuing execution. Threads that finish execution are removed
		from the scheduler.</p>
		
	<pre>
	function firstRun() {
		::print("Start!");
	}
	
	function ping() {
		while(true) {
			::print("Ping...");
			::suspend();
		}
	}
	
	function pong() {
		while(true) {
			::print("Pong...");
			::suspend();
		}
	}

	thread.schedule(firstRun); // Will only run once
	thread.schedule(ping);
	thread.schedule(pong);
	thread.run(); // ping and pong will alternate forever.
	</pre>
	
		<p>Threads can be added to the scheduler while it is running too, which allows for an
		alternate version of the above code:</p>
		
	<pre>
	function ping() {
		::print("Ping...");
		thread.schedule(pong);
	}
	
	function pong() {
		::print("Pong...");
		thread.schedule(ping);
	}

	thread.schedule(ping);
	thread.run(); // ping and pong will alternate forever.
	</pre>
	
		<h3 id="run"><b>run</b>()</h3>
		
		<p>run executes any currently scheduled threads, blocking until the all scheduled threads
		have completed.</p>
		
		<h3 id="sleep"><b>sleep</b>(<i>duration</i>)</h3>
		
		<p>sleep will suspend the execution of a thread for at least the time span indicated by 
		<i>duration</i>, which is provided in seconds as a float. In order for sleep to be effective
		the thread must be woken up at a regular interval, and therefore it is recommended that sleep
		is used in conjunction with schedule.</p>
		
		<p>If a sleeping thread is woken up before the sleep duration is passed the thread will 
		immediately suspend execution again. Calling sleep with a duration of 0 is synonymous with 
		calling suspend directly.</p>
		
	<pre>
	thread &lt;- ::import("sqratthread", {});
	
	function countSeconds() {
		local i = 0;
		while(true) {
			::print(i + " seconds");
			i++;
			thread.sleep(1.0);
		}
	}
	
	function countFiveSeconds() {
		local i = 0;
		while(true) {
			::print(i + " is a multiple of 5!");
			i+=5;
			thread.sleep(5.0);
		}
	}
	
	thread.schedule(countSeconds);
	thread.schedule(countFiveSeconds);
	thread.run();
	</pre>
	
		<p>The expected output of the above script is every second a new "x seconds" message is printed, 
		and every five seconds  "x is a multiple of 5" is printed.</p>
		
	<pre>
	1 seconds
	2 seconds
	3 seconds
	4 seconds
	5 seconds
	5 is a multiple of 5!
	6 seconds
	7 seconds
	8 seconds
	9 seconds
	10 seconds
	10 is a multiple of 5!
	...
	</pre>
	
		<h3 id="getthread"><i>thread</i> <b>getthread</b>()</h3>
		
		<p>getthread returns the currently executing thread object. This function is primarily intended to 
		allow threads to pass self references between themselves to facilitate easier dynamic wakeup logic.</p>
		
	</div>
	</body>
</html>